package pl.edu.mimuw.irs.rcp.view.requirements;

import org.eclipse.gef.EditDomain;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.part.ViewPart;

import pl.edu.mimuw.irs.core.model.design.net.IRSRequirement;
import pl.edu.mimuw.irs.core.model.design.resource.Requirements;
import pl.edu.mimuw.irs.rcp.controller.editor.requirements.RequirementsTreeWrapper;
import pl.edu.mimuw.irs.rcp.controller.editor.workflow.IRSWorkflowEditor;
import pl.edu.mimuw.irs.rcp.controller.editor.workflow.part.IRSRequirementEditPart;
import pl.edu.mimuw.irs.rcp.util.MessageCode;
import pl.edu.mimuw.irs.rcp.util.UITexts;

/**
 * @author Jakub Rauch
 * Created on: 2009-05-25
 */
public class RequirementsView extends ViewPart {

	public static final String ID = "pl.edu.mimuw.irs.view.requirements";

	// *** Attributes
	
	private RequirementsTreeWrapper tree;
	private Object lastSelection;
	private IEditorInput input;
	private Composite composite;
	private IPartListener partListener = new IPartListener() {

		@Override
		public void partActivated(IWorkbenchPart sourcepart) {
			if (!(sourcepart instanceof IEditorPart)) return;
			if (sourcepart instanceof IRSWorkflowEditor) {
				IRSWorkflowEditor editor = (IRSWorkflowEditor) sourcepart;
				input = editor.getEditorInput();
			}
		}

		@Override
		public void partBroughtToTop(IWorkbenchPart part) {
			
		}

		@Override
		public void partClosed(IWorkbenchPart part) {
			if (!(part instanceof IEditorPart)) return;
			editorClosed((IEditorPart) part);
		}

		@Override
		public void partDeactivated(IWorkbenchPart part) {
			
		}

		@Override
		public void partOpened(IWorkbenchPart part) {
			
		}
		
	};
	private ISelectionListener listener = new ISelectionListener() {
		@Override
		public void selectionChanged(IWorkbenchPart sourcepart, ISelection selection) {
			/* 
			 * We ignore the same elements selection and those which are not from IRSRequirementEditPart.
			 */
			if (!(sourcepart instanceof IEditorPart)) return;
			if (sourcepart instanceof IRSWorkflowEditor) {
				IRSWorkflowEditor editor = (IRSWorkflowEditor) sourcepart;
				if (selection instanceof StructuredSelection) {
					StructuredSelection structuredSelection = (StructuredSelection) selection;
					if (structuredSelection.getFirstElement() != lastSelection) {
						lastSelection = structuredSelection.getFirstElement();
						if (structuredSelection.getFirstElement() instanceof IRSRequirementEditPart) {
							IRSRequirementEditPart editPart = (IRSRequirementEditPart) structuredSelection.getFirstElement();
							changeSelection(editor, editPart);
						    if (!isVisible()) {
						    	show();
						    }
					    	return;
						}
					}
				}
			}
			if (isVisible()) {
				hide();
			}
		}
	};
	public RequirementsTreeWrapper getTree() {
		return tree;
	}
	
	// *** Constructors

	public RequirementsView() {
		super();
	}

	// *** Methods

	private void editorClosed(IEditorPart editorPart) {
		if (editorPart.getEditorInput() == input) {
			input = null;
			tree.setRequirements(null);
			hide();
		}
	}
	
	private boolean isVisible() {
		return composite.getVisible();
	}
	
	private void hide() {
		composite.setVisible(false);
		setContentDescription(UITexts.get(MessageCode.REQUIREMENTS_VIEW_UNASSIGNED_DESCRIPTION));
	}
	
	private void show() {
		composite.setVisible(true);
		setContentDescription("");
	}
	
	
	private void changeSelection(IRSWorkflowEditor sourcepart,
			IRSRequirementEditPart selection) {
		/*
		 * Get the IProject to access its session properties for Roles
		 */
		IRSRequirement irsRequirement = selection.getIRSRequirement();
		Requirements requirements = irsRequirement.getRequirements();
		
		/*
		 * Here we have requirements.
		 */
		input = sourcepart.getEditorInput();
		if (tree.getRequirements() != requirements) {
			tree.setEditDomain(sourcepart.getEditDomain());
			tree.setRequirements(requirements);
			tree.redrawTree();
			if (!isVisible()) show();
		}
	}
	
	/**
	 * This is a callback that will allow us to create the viewer and initialize
	 * it.
	 */
	public void createPartControl(Composite parent) {
		/*Composite composite = new Composite(parent, SWT.NULL);
		
	    // create the desired layout for this wizard page
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 1;
		composite.setLayout(gridLayout);
		parent.setLayout(gridLayout);*/
		
		composite = parent;
		hide();
		
		tree = new RequirementsTreeWrapper(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, null, null);
		getSite().setSelectionProvider(tree.getTreeViewer());
		getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(listener);
		getSite().getPage().addPartListener(partListener);
	}

	@Override
	public void dispose() {

		getSite().getWorkbenchWindow().getSelectionService().removeSelectionListener(listener);
		getSite().getPage().removePartListener(partListener);
		
		super.dispose();
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		tree.getTreeViewer().getControl().setFocus();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public Object getAdapter(Class adapter) {
		if (adapter == CommandStack.class)
			if (tree != null) return tree.getCommandStack();
		else if (adapter == EditDomain.class)
			if (tree != null) return tree.getEditDomain();

		return super.getAdapter(adapter);
	}
}
